﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;

namespace vueweb
{
	public abstract partial class BaseController : Controller
	{
		public IServiceProvider _serviceProvider;
		public HttpContext _httpContext;
		public ISession _session;
		public ActionDescriptor _actionDescriptor;
		public BinarySerializer _serializer;
		public string _rootUrl;
		public IWebHostEnvironment env;
		private string cookiename = CommonTools.Config.GetValue<string>("root:session:cookiename");

		public BaseController()
		{
			_serviceProvider = Singleton<IServiceProvider>.Instance;
			_httpContext = ((IHttpContextAccessor)_serviceProvider.GetService(typeof(IHttpContextAccessor))).HttpContext;
			_session = _httpContext.Session;
			_serializer = new BinarySerializer();
			env = Singleton<IWebHostEnvironment>.Instance;
		}

		public override void OnActionExecuting(ActionExecutingContext context)
		{
			_actionDescriptor = context.ActionDescriptor;

			string token = Request.Query["token"];
			if (!string.IsNullOrEmpty(token))
			{
				_session.SetSessionKey(token);
			}

			if (IsDirectAccessAction())
			{
				return;
			}

			if (CurrentLoginUser == null)
			{
				if (IsAjax)
				{
					context.Result = new JsonResult(new { code = 50014, message = "会话过期，将重新登录" });
				}
				else
				{
					context.Result = RedirectToAction("app", "home");
				}
				return;
			}
		}

		public override void OnActionExecuted(ActionExecutedContext context)
		{
			base.OnActionExecuted(context);
		}

		protected string JsonContentType
		{
			get { return "application/json; charset=utf-8"; }
		}

		protected bool IsDirectAccessAction()
		{
			return _actionDescriptor.FilterDescriptors.FirstOrDefault(item => item.Filter is DirectAccessActionAttribute) != null;
		}

		protected SysUserEntity CurrentLoginUser
		{
			get
			{
				byte[] buf = _session.Get("SysUserEntity");
				object v = _serializer.Deserialize(buf);
				if (v != null)
				{
					return (SysUserEntity)v;
				}
				return null;
			}
			set
			{
				byte[] buf = _serializer.Serialize(value);
				_session.Set("SysUserEntity", buf);
			}
		}

		protected bool IsAjax
		{
			get
			{
				if (Request.Headers != null)
					return !string.IsNullOrEmpty(Request.Headers["X-Token"]);
				return false;
			}
		}

		protected bool IsPost
		{
			get
			{
				return Request.Method.ToLower() == "post";
			}
		}

		protected bool IsDevLogined
		{
			get
			{
				return _session.Get<bool>("IsDevLogined");
			}

			set
			{
				_session.Set<bool>("IsDevLogined", value);
			}
		}

		protected string ipFromSource;

		protected string RemoteClientIp
		{
			get
			{
				ipFromSource = "X-Real-IP";
				string ip = Request.Headers["X-Real-IP"];
				if (string.IsNullOrEmpty(ip) || "unknown" == ip.ToLower())
				{
					ip = Request.Headers["X-Forwarded-For"];
					ipFromSource = "X-Forwarded-For";
				}
				if (string.IsNullOrEmpty(ip) || "unknown" == ip.ToLower())
				{
					ip = Request.Headers["Proxy-Client-IP"];
					ipFromSource = "Proxy-Client-IP";
				}
				if (string.IsNullOrEmpty(ip) || "unknown" == ip.ToLower())
				{
					ip = Request.Headers["WL-Proxy-Client-IP"];
					ipFromSource = "WL-Proxy-Client-IP";
				}
				if (string.IsNullOrEmpty(ip) || "unknown" == ip.ToLower())
				{
					ip = HttpContext.Connection.RemoteIpAddress.ToString();
					ipFromSource = "RemoteIpAddress";
				}
				return ip;
			}
		}

		protected string Token
		{
			get
			{
				return _session.GetSessionToken();
			}
		}


		public string WebRequestPostAndGetRes(string sUrl, string sParam)
		{
			byte[] bt = System.Text.Encoding.UTF8.GetBytes(sParam);
			Uri uriurl = new Uri(sUrl);
			HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uriurl);
			req.Method = "Post";
			req.Timeout = 120 * 1000;
			req.ContentType = "application/x-www-form-urlencoded;";
			req.ContentLength = bt.Length;

			using (Stream reqStream = req.GetRequestStream())
			{
				reqStream.Write(bt, 0, bt.Length);
				reqStream.Flush();
			}
			try
			{
				using (WebResponse res = req.GetResponse())
				{
					Stream resStream = res.GetResponseStream();
					StreamReader resStreamReader = new StreamReader(resStream, System.Text.Encoding.UTF8);
					string resLine;
					System.Text.StringBuilder resStringBuilder = new System.Text.StringBuilder();

					while ((resLine = resStreamReader.ReadLine()) != null)
					{
						resStringBuilder.Append(resLine + System.Environment.NewLine);
					}

					resStream.Close();
					resStreamReader.Close();
					return resStringBuilder.ToString();
				}
			}
			catch (Exception ex)
			{
				return ex.Message;
			}
		}
	}

	public partial class TbUser
	{
		public string UserGuid { get; set; }
		public string UserUid { get; set; }
		public string UserName { get; set; }
		public string UserPwd { get; set; }
		public int? Source { get; set; }
		public string FkSourceGuid { get; set; }
		public string FkSourceCode { get; set; }
		public string FkSourceName { get; set; }
		public int? State { get; set; }
		public string FkCreUserguid { get; set; }
		public string FkCreUsername { get; set; }
		public DateTime? CreTime { get; set; }
		public string FkUpdUserguid { get; set; }
		public string FkUpdUsername { get; set; }
		public DateTime? UpdTime { get; set; }
	}

	public partial class TbMaterialTypes
	{
		public string TypeGuid { get; set; }
		public string TypeCode { get; set; }
		public string TypeName { get; set; }
		public string Pguid { get; set; }
		public int? Sort { get; set; }
		public DateTime? CreTime { get; set; }
		public string FkCreUserGuid { get; set; }
		public string FkCreUserCode { get; set; }
		public string FkCreUserName { get; set; }
		public DateTime? UpdTime { get; set; }
		public string FkUpdUserGuid { get; set; }
		public string FkUpdUserCode { get; set; }
		public string FkUpdUserName { get; set; }
		public string ProductType { get; set; }
	}

	[Serializable]
	public class SysUserEntity 
	{
		/// <summary>
		/// 用户GUID
		/// </summary>
		public string UserGuid { get; set; }
		/// <summary>
		/// 用户编号
		/// </summary>
		public string UserUid { get; set; }
		/// <summary>
		/// 用户名称
		/// </summary>
		public string UserName { get; set; }
		/// <summary>
		/// 用户密码
		/// </summary>
		public string UserPwd { get; set; }
		/// <summary>
		/// 用户状态 1 正常，0 禁用
		/// </summary>
		public long? State { get; set; }
		/// <summary>
		/// 反馈信息
		/// </summary>
		public string Msg { get; set; }
	}

}
